use axum::{
    routing::{get, post, put, delete},
    Router, 
    response::{IntoResponse},
    http::{StatusCode,Method},
    handler::Handler, 
    extract::Extension, 
};
use serde_json::json;
use sqlx::postgres::PgPoolOptions;
use tower::ServiceBuilder;
use tower_http::{ServiceBuilderExt};
use momo_main_sever::handler::user;
use std::{net::SocketAddr, time::Duration};
use tower_http::cors::{Any,CorsLayer};

#[tokio::main]
async fn main() -> anyhow::Result<(), anyhow::Error> {
    if std::env::var_os("RUST_LOG").is_none() {
        std::env::set_var("RUST_LOG", "example_tokio_postgres=debug")
    }

    tracing_subscriber::fmt::init();

    let pool = PgPoolOptions::new()
        .max_connections(20)
        .acquire_timeout(Duration::from_secs(8))
        .connect("postgres://postgres:youpassword@localhost/youdb")
        .await
        .expect("数据库连接失败");

    let mid = ServiceBuilder::new()
        .layer(Extension(pool))
        .compression();

    let app = Router::new()
        .route("/",get(handler_404))
        .route("/add/user", post(user::add_user))
        .layer(
            CorsLayer::new()
                .allow_origin(Any)
                .allow_headers(Any)
                .allow_methods([Method::GET,Method::OPTIONS,Method::POST,Method::PUT,Method::DELETE])
        )
        .layer(mid);
    
    
    let app = app.fallback(handler_404.into_service());

    let addr = SocketAddr::from(([127, 0, 0, 1], 41080));

    tracing::debug!("listening on {}", addr);

    axum::Server::bind(&addr)
        .serve(app.into_make_service())
        .await
        .unwrap();
    Ok(())    
}

async fn handler_404() -> impl IntoResponse {
    (StatusCode::NOT_FOUND, axum::Json(json!({
        "msg": "页面不存在",
        "success":false,
    })))
}
